package com.xingchi.tornado.security.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xingchi.tornado.basic.Result;
import com.xingchi.tornado.security.config.SecurityProperties;
import com.xingchi.tornado.security.model.IUser;
import com.xingchi.tornado.security.model.LoginData;
import com.xingchi.tornado.security.model.UnifiedAuthenticationToken;
import com.xingchi.tornado.security.service.LoginSourceManager;
import com.xingchi.tornado.security.service.LoginTypeManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * 默认认证成功处理器
 *
 * @author xingchi
 * @date 2025/3/9 20:47
 */
@Slf4j
public class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final ObjectMapper objectMapper;
    private final SecurityProperties properties;
    private final SessionAttributeServiceDecorator sessionAttributeServiceDecorator;

    public DefaultAuthenticationSuccessHandler(ObjectMapper objectMapper, SecurityProperties properties, SessionAttributeServiceDecorator sessionAttributeServiceDecorator) {
        this.objectMapper = objectMapper;
        this.properties = properties;
        this.sessionAttributeServiceDecorator = sessionAttributeServiceDecorator;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 响应
        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);

        UnifiedAuthenticationToken unifiedAuthenticationToken = (UnifiedAuthenticationToken) authentication;

        HttpSession session = request.getSession(false);
        String sessionId = session.getId();
        LoginData<? extends IUser> loginData = unifiedAuthenticationToken.getLoginData();
        loginData.setSessionId(sessionId);

        // 填充session属性
        sessionAttributeServiceDecorator.fillSessionAttribute(session, loginData);

        Result<Object> result = Result.ok(((UnifiedAuthenticationToken) authentication).getLoginData());
        result.setMessage("登录成功");
        log.info("用户登录成功，userId: {}, sessionId: {}, 登录来源：{}, 登录方式：{}, 登录ip: {}",
                loginData.getUserId(),
                sessionId,
                LoginSourceManager.getInstance(loginData.getLoginSource()).getName(),
                LoginTypeManager.getInstance(loginData.getLoginType()).getName(),
                loginData.getIp());
        response.getWriter().println(objectMapper.writeValueAsString(result));
    }
}
